package com.lwbldy.common.tools;

import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemReader;

import javax.crypto.Cipher;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.io.StringWriter;
//import java.security.KeyFactory;
//import java.security.PrivateKey;
//import java.security.Security;
//import java.security.interfaces.RSAPrivateCrtKey;
//import java.security.spec.EncodedKeySpec;
//import java.security.spec.InvalidKeySpecException;
//import java.security.spec.PKCS8EncodedKeySpec;
//import java.security.spec.RSAPrivateKeySpec;
//import java.util.List;

//import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Object;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
//import org.bouncycastle.asn1.ASN1Primitive;
//import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
//import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.util.io.pem.PemObject;
//import org.bouncycastle.util.io.pem.PemReader;
import org.bouncycastle.util.io.pem.PemWriter;
//import org.bouncycastle.openssl.MiscPEMGenerator;
//import org.bouncycastle.openssl.PKCS8Generator;


//import com.ctrip.lzyan.test.cipher.cscm.RsaPemUtil;
//import com.google.common.base.Joiner;
//import com.google.common.base.Splitter;
//import com.google.common.base.Strings;

//import com.google.common.collect.Lists;
import org.apache.commons.codec.binary.Base64;

public class SingUtil2 {
//    private static final String COMMENT_BEGIN_FLAG = "-----";
//    private static final String RETURN_FLAG_R = "\r";
//    private static final String RETURN_FLAG_N = "\n";



    //format PKCS#8 to PKCS#1
    public static String formatPkcs8ToPkcs1(String rawKey) throws Exception {
        String result = null;
        //extract valid key content
        String validKey = rawKey;//RsaPemUtil.extractFromPem(rawKey); // pem文件多行合并为一行
//        if(!Strings.isNullOrEmpty(validKey))
        if (validKey != null)
        {
            //将BASE64编码的私钥字符串进行解码
            byte[] encodeByte = Base64.decodeBase64(validKey);

            //==========
            //pkcs8Bytes contains PKCS#8 DER-encoded key as a byte[]
            PrivateKeyInfo pki = PrivateKeyInfo.getInstance(encodeByte);
            RSAPrivateKeyStructure pkcs1Key = RSAPrivateKeyStructure.getInstance(pki.getPrivateKey());
            byte[] pkcs1Bytes = pkcs1Key.getEncoded();//etc.
            //==========

            String type = "RSA PRIVATE KEY";
            result = format2PemString(type, pkcs1Bytes);
        }
        return result;
    }

    //format PKCS#1 to PKCS#8
    public static String formatPkcs1ToPkcs8(String rawKey) throws Exception {
        String result = null;
        //extract valid key content
        String validKey = rawKey;//RsaPemUtil.extractFromPem(rawKey); // pem文件多行合并为一行
//        if(!Strings.isNullOrEmpty(validKey))
        if (validKey != null)
        {
            //将BASE64编码的私钥字符串进行解码
            byte[] encodeByte = Base64.decodeBase64(validKey);

            AlgorithmIdentifier algorithmIdentifier = new AlgorithmIdentifier(PKCSObjectIdentifiers.pkcs8ShroudedKeyBag);    //PKCSObjectIdentifiers.pkcs8ShroudedKeyBag
//            ASN1Object asn1Object = ASN1Object.fromByteArray(encodeByte);
            ASN1Object asn1Object = ASN1ObjectIdentifier.fromByteArray(encodeByte);
            PrivateKeyInfo privKeyInfo = new PrivateKeyInfo(algorithmIdentifier, asn1Object);
            byte[] pkcs8Bytes = privKeyInfo.getEncoded();

            String type = "PRIVATE KEY";
//            result = format2PemString(type, pkcs8Bytes); // 格式化为pem多行格式输出
            return Base64.encodeBase64String(pkcs8Bytes); // 直接一行字符串输出

        }
        return result;
    }

    // Write to pem file
    // 字符串换行显示
    private static String format2PemString(String type, byte[] privateKeyPKCS1) throws Exception {
        PemObject pemObject = new PemObject(type, privateKeyPKCS1);
        StringWriter stringWriter = new StringWriter();
        PemWriter pemWriter = new PemWriter(stringWriter);
        pemWriter.writeObject(pemObject);
        pemWriter.close();
        String pemString = stringWriter.toString();
        return pemString;
    }

    //=== Testing ===
    public static void main(String[] args) throws Exception {
        String rawKey_pkcs1 = "";
        String rawKey_pkcs8 = "";

        rawKey_pkcs1 = "MIICXQIBAAKBgQCekK3y7egD2Yrt2BfgEESGPAZAfDiDYiie//WUhO/lDqdn+onj\n" +
                "i2396fZuC7MwajE0b+Bwb1fZKbv2q/TZiwNOzD9Ave6vt/tCiKZvCuk3YbPO6zJP\n" +
                "Nc2qPFUkQnRKuaR6xRn6eWwp45gzJZRUVIAJ5lf7mDyisx78y8yljjBcSQIDAQAB\n" +
                "AoGAT+rtsT3VLXOMgRnj1qt8Tgecww2Y0ic7//9TwDpMSq9bEp4Et2nD0zEDYi2F\n" +
                "b8Zl7F7iyOhlZ2+Qa9/5NVfKHza95pdGsce++iLxI+iqlHjVjUMOwuGy3mKbWGmW\n" +
                "Ov+JcTy13WUm0rlee/WRnMLqfqcSJkUsMY3eQxvDvPJzmXECQQDQfbgoWjh1lhRP\n" +
                "pPYfZlO/J/NcrHooI+J9hNADHo+LEnKsa9Hx6uVj60FOajt4RQc05vSMVSxq9QUK\n" +
                "nEZGCrMdAkEAwrKKuNV1munJ/R34qW2w6e8hY9GHo83JmBB8Yv8r3YG2FOO+N+hg\n" +
                "4vaGAKHAWQoOJMhuxiHkxQXKIt37JYO6HQJBAI7Km9cfO23lNNH7ZAnLVm4kWXvO\n" +
                "MPfO4+8diC2qv5r7LojCa46pVyQg2qBvB33uoOnth+2Y5Av49dP3hfWwnE0CQQC1\n" +
                "BdghPqcYH+MkKqe2sDxbZXFAI+LflEip0Do2uVYJn76x8YY86RycKeYx1DLJFqZL\n" +
                "4OfN5FmWLmngvU/zc2SpAkBXD/i16MIHUKZfR5YWASeZ2SNlp3fCwV1otZhDdGba\n" +
                "PGCCmfhb9jKG4rwJOTidRP0KZ0aJsFaaphuWubgxwyWo";
        rawKey_pkcs8 = "MIICXQIBAAKBgQCekK3y7egD2Yrt2BfgEESGPAZAfDiDYiie//WUhO/lDqdn+onj\n" +
                "i2396fZuC7MwajE0b+Bwb1fZKbv2q/TZiwNOzD9Ave6vt/tCiKZvCuk3YbPO6zJP\n" +
                "Nc2qPFUkQnRKuaR6xRn6eWwp45gzJZRUVIAJ5lf7mDyisx78y8yljjBcSQIDAQAB\n" +
                "AoGAT+rtsT3VLXOMgRnj1qt8Tgecww2Y0ic7//9TwDpMSq9bEp4Et2nD0zEDYi2F\n" +
                "b8Zl7F7iyOhlZ2+Qa9/5NVfKHza95pdGsce++iLxI+iqlHjVjUMOwuGy3mKbWGmW\n" +
                "Ov+JcTy13WUm0rlee/WRnMLqfqcSJkUsMY3eQxvDvPJzmXECQQDQfbgoWjh1lhRP\n" +
                "pPYfZlO/J/NcrHooI+J9hNADHo+LEnKsa9Hx6uVj60FOajt4RQc05vSMVSxq9QUK\n" +
                "nEZGCrMdAkEAwrKKuNV1munJ/R34qW2w6e8hY9GHo83JmBB8Yv8r3YG2FOO+N+hg\n" +
                "4vaGAKHAWQoOJMhuxiHkxQXKIt37JYO6HQJBAI7Km9cfO23lNNH7ZAnLVm4kWXvO\n" +
                "MPfO4+8diC2qv5r7LojCa46pVyQg2qBvB33uoOnth+2Y5Av49dP3hfWwnE0CQQC1\n" +
                "BdghPqcYH+MkKqe2sDxbZXFAI+LflEip0Do2uVYJn76x8YY86RycKeYx1DLJFqZL\n" +
                "4OfN5FmWLmngvU/zc2SpAkBXD/i16MIHUKZfR5YWASeZ2SNlp3fCwV1otZhDdGba\n" +
                "PGCCmfhb9jKG4rwJOTidRP0KZ0aJsFaaphuWubgxwyWo";

        String formatKey1 = formatPkcs1ToPkcs8(rawKey_pkcs1);
//        String formatKey2 = formatPkcs8ToPkcs1(rawKey_pkcs8);
        System.out.println(formatKey1);
//        System.out.println(formatKey2);
    }

}

